import { defineStore } from "pinia";
import { useUser } from "./useUser";
import { useNotification } from "./useNotification";
import { equipEquipTypeZip, equipAllEquipByUserZip, equipNowInfoAllNowInfoZip, equipeditEquipEdit, equipHistoryAllInfosZip, equipV3EquipEdit, equipUserAuthority } from "@/apis/equip";
import { equipsRegData } from "@/common/global/equipRegData";
import { defaultEquipInfoCheck, equipRegDataUnify, getEquipImageURL, getEquipInfo } from "@/utils/equip";
import { regAIAOParse, regDIDOParse } from "@/utils/parse";
import { deepClone } from "@/utils/conversion";
import { objToEditArr, unpack } from "@/utils/business";
import default_equip_info from "@/assets/data/default_equip_info.json";

export const useEquip = defineStore("equip", {
    state() {
        return {
            equipsType: [] as Equip.EquipType[],
            equipsInfo: [] as Equip.EquipInfo[],
            groupsName: [] as string[],
        };
    },
    getters: {
        // 分组后的设备信息
        equipsInfoGroup() {
            let equipsInfoGroup: { groupName: string; equipsInfo: Equip.EquipInfo[] }[] = [];
            this.equipsInfo.forEach((equipInfo: Equip.EquipInfo) => {
                let item = equipsInfoGroup.find((v) => v.groupName == equipInfo.fGroup);
                item ? item.equipsInfo.push(equipInfo) : equipsInfoGroup.push({ groupName: equipInfo.fGroup, equipsInfo: [equipInfo] });
            });
            const collator = new Intl.Collator("zh-Hans-CN", { sensitivity: "accent" });
            equipsInfoGroup.forEach((v) => v.equipsInfo.sort((a, b) => collator.compare(a.fName, b.fName)));
            return equipsInfoGroup.sort((a, b) => collator.compare(a.groupName, b.groupName));
        },
    },
    actions: {
        setState({ equipsType, equipsInfo, equipsRegData: tempEquipsRegData, groupsName }: { equipsType?: Equip.EquipType[]; equipsInfo?: Equip.EquipInfo[]; equipsRegData?: Equip.EquipRegData[]; groupsName?: string[] }) {
            if (equipsType !== undefined) this.equipsType = equipsType;
            if (equipsInfo !== undefined) this.equipsInfo = equipsInfo;
            if (tempEquipsRegData !== undefined) {
                equipsRegData.length = 0;
                equipsRegData.push(...tempEquipsRegData);
            }
            if (groupsName !== undefined) this.groupsName = groupsName;
        },
        restoreState() {
            this.equipsType.length = 0;
            this.equipsInfo.length = 0;
            equipsRegData.length = 0;
            this.groupsName.length = 0;
        },
        // 同步设备类型
        syncEquipsType() {
            return new Promise(async (resolve) => {
                let data: Equip.EquipType[] = unpack((await equipEquipTypeZip()).data.data);
                this.equipsType.length = 0;
                this.equipsType.push(...data);
                resolve(null);
            });
        },
        // 同步所有设备信息
        syncEquipsInfo() {
            return new Promise(async (resolve) => {
                const notification = useNotification();
                const testEquipInfo = deepClone(default_equip_info as Equip.EquipInfo);
                testEquipInfo.fID = "test1";
                testEquipInfo.fUNID = "test1";
                testEquipInfo.dtAI = [
                    { index: 0, name: "空气温度", alarm: 0, value: null, unit: "℃", alarmL: 15, alarmH: 30, alarmImg: "", img: "", x1: 0, x2: 0, y1: 0, y2: 0 },
                    { index: 1, name: "空气湿度", alarm: 0, value: null, unit: "%", alarmL: 40, alarmH: 70, alarmImg: "", img: "", x1: 0, x2: 0, y1: 0, y2: 0 },
                    { index: 2, name: "土壤温度", alarm: 0, value: null, unit: "℃", alarmL: 15, alarmH: 25, alarmImg: "", img: "", x1: 0, x2: 0, y1: 0, y2: 0 },
                    { index: 3, name: "土壤湿度", alarm: 0, value: null, unit: "%", alarmL: 60, alarmH: 80, alarmImg: "", img: "", x1: 0, x2: 0, y1: 0, y2: 0 },
                    { index: 4, name: "酸碱度", alarm: 0, value: null, unit: "", alarmL: 6, alarmH: 7.5, alarmImg: "", img: "", x1: 0, x2: 0, y1: 0, y2: 0 },
                    { index: 5, name: "光照强度", alarm: 0, value: null, unit: "lux", alarmL: 20000, alarmH: 100000, alarmImg: "", img: "", x1: 0, x2: 0, y1: 0, y2: 0 },
                    { index: 6, name: "电导率", alarm: 0, value: null, unit: "dS/m", alarmL: 0.5, alarmH: 3, alarmImg: "", img: "", x1: 0, x2: 0, y1: 0, y2: 0 },
                    { index: 7, name: "二氧化碳浓度", alarm: 0, value: null, unit: "ppm", alarmL: 800, alarmH: 1500, alarmImg: "", img: "", x1: 0, x2: 0, y1: 0, y2: 0 },
                ];
                this.equipsInfo.push(testEquipInfo);
                performance.mark("equipsInfoDataStart");
                let data: Equip.EquipInfo[] = unpack((await equipAllEquipByUserZip()).data.data);
                performance.mark("equipsInfoDataEnd");
                performance.measure("equipsInfoDataDone", "equipsInfoDataStart", "equipsInfoDataEnd");
                const measure = performance.getEntriesByName("equipsInfoDataDone")[0];
                notification.addNotice({
                    id: notification.notices.length.toString(),
                    type: "performance",
                    title: "性能参数",
                    message: "设备信息接口获取并解压用时：" + measure?.duration.toFixed(1) + "ms",
                    state: 0,
                    date: Date.now(),
                });
                performance.clearMarks("equipsInfoDataStart");
                performance.clearMarks("equipsInfoDataEnd");
                performance.clearMeasures("equipsInfoDataDone");
                data.forEach((equipInfo) => {
                    let item = this.equipsInfo.find((v: Equip.EquipInfo) => v.fID == equipInfo.fID);
                    if (item) for (let key in equipInfo) (item as any)[key] = equipInfo[key as keyof typeof equipInfo];
                    else {
                        equipInfo.isDlcDam = false;
                        equipInfo.isLora = false;
                        equipInfo.isHostLora = false;
                        equipInfo.access = deepClone(default_equip_info.access);
                        equipInfo.online = false;
                        equipInfo.alarm = false;
                        equipInfo.dtAI = [];
                        equipInfo.dtAO = [];
                        equipInfo.dtDI = [];
                        equipInfo.dtDO = [];
                        equipInfo.dlc = deepClone(default_equip_info.dlc);
                        equipInfo.lora = { comm: null, work: null, time: null };
                        equipInfo.adjust = { ai: null };
                        equipInfo.histories = [];
                        this.equipsInfo.push(equipInfo);
                    }
                });
                resolve(null);
            });
        },
        // 同步所有设备权限
        syncEquipsAccess() {
            return new Promise(async (resolve) => {
                const user = useUser();
                let { data } = await equipUserAuthority();
                data.data.forEach((v: any) => {
                    const equipInfo = getEquipInfo({ fid: v.fEquipID });
                    if (equipInfo) {
                        if (equipInfo.fUserID == user.userInfo.usrid) {
                            equipInfo.access.fRead = true;
                            equipInfo.access.fOpr = true;
                            equipInfo.access.fEdit = true;
                            equipInfo.access.fDelete = true;
                            equipInfo.access.fCamera = true;
                        } else {
                            equipInfo.access.fRead = Boolean(v.fRead);
                            equipInfo.access.fCamera = Boolean(v.fCamera);
                            equipInfo.access.fOpr = Boolean(v.fOpr);
                            equipInfo.access.fEdit = Boolean(v.fEdit);
                            equipInfo.access.fDelete = Boolean(v.fDelete);
                        }
                    }
                });
                resolve(null);
            });
        },
        // 同步所有设备状态
        syncEquipsRegData() {
            return new Promise(async (resolve) => {
                let data: Equip.EquipRegData[] = unpack((await equipNowInfoAllNowInfoZip()).data.data);
                data.forEach((equipRegData) => {
                    equipRegData = equipRegDataUnify(equipRegData);
                    equipRegData.regao = [];
                    let item = equipsRegData.find((v: Equip.EquipRegData) => v.sn == equipRegData.sn);
                    if (item) for (let key in equipRegData) (item as any)[key] = equipRegData[key as keyof typeof equipRegData];
                    else equipsRegData.push(equipRegData);
                });
                resolve(null);
            });
        },
        // 同步单个设备的历史数据
        syncEquipHistory({ fid, funid, begintime, endtime, second }: { fid?: string; funid?: string; begintime: string; endtime: string; second: string | number }) {
            return new Promise(async (resolve, reject) => {
                const notification = useNotification();
                const equipInfo = (this.equipsInfo as Equip.EquipInfo[]).find((v) => v.fID == fid || v.fUNID == funid);
                const equipType = (this.equipsType as Equip.EquipType[]).find((v) => v.fEquipType == equipInfo?.fEquipType);
                if (equipInfo && equipType) {
                    let { data } = await equipHistoryAllInfosZip({ unid: equipInfo.fUNID, begintime, endtime, second });
                    if (data.code === 200) {
                        equipInfo.histories.length = 0;
                        const sortAI = deepClone(equipInfo.dtAI).sort((a, b) => a.index - b.index);
                        let historiesRegData = JSON.parse(unpack(data.data));
                        performance.mark("equipHistoryRegDataStart");
                        equipInfo.histories = this.equipHistoryRegDataComputed({
                            historiesRegData,
                            aiX1s: sortAI.map((v) => v.x1),
                            aiY1s: sortAI.map((v) => v.y1),
                            aiX2s: sortAI.map((v) => v.x2),
                            aiY2s: sortAI.map((v) => v.y2),
                            diNum: equipType.fDINum,
                            doNum: equipType.fDONum,
                        });
                        performance.mark("equipHistoryRegDataEnd");
                        performance.measure("equipHistoryRegDataDone", "equipHistoryRegDataStart", "equipHistoryRegDataEnd");
                        const measure = performance.getEntriesByName("equipHistoryRegDataDone")[0];
                        notification.addNotice({
                            id: notification.notices.length.toString(),
                            type: "performance",
                            title: "性能参数",
                            message: equipInfo.fName + "历史数据处理完毕，共计：" + equipInfo.histories.length + "条数据，用时：" + measure?.duration.toFixed(1) + "ms",
                            state: 0,
                            date: Date.now(),
                        });
                        performance.clearMarks("equipHistoryRegDataStart");
                        performance.clearMarks("equipHistoryRegDataEnd");
                        performance.clearMeasures("equipHistoryRegDataDone");
                        resolve(null);
                    } else reject();
                }
                resolve(null);
            });
        },
        // 更新单个设备reg数据
        updateEquipRegData({ equipRegData }: { equipRegData: Equip.EquipRegData }) {
            let index = equipsRegData.findIndex((v: Equip.EquipRegData) => v.sn == equipRegData.sn);
            if (index != -1) for (let key in equipRegData) (equipsRegData as any)[index][key] = equipRegData[key as keyof typeof equipRegData];
            else equipsRegData.push(equipRegData);
            this.equipRegDataComputed({
                funid: equipRegData.sn as string,
                online: Boolean(equipRegData.isOnline),
                regAI: equipRegData.regai,
                regDI: equipRegData.regdi,
                regDO: equipRegData.regdo,
                diNum: equipRegData.dinum,
                doNum: equipRegData.donum,
            });
        },
        // 计算所有设备信息和所有设备数据
        computedEquips() {
            return new Promise(async (resolve) => {
                const notification = useNotification();
                performance.mark("equipsInfoParseStart");
                await this.equipsInfoComputed();
                performance.mark("equipsInfoParseEnd");
                performance.measure("equipsInfoParseDone", "equipsInfoParseStart", "equipsInfoParseEnd");
                const measure = performance.getEntriesByName("equipsInfoParseDone")[0];
                notification.addNotice({
                    id: notification.notices.length.toString(),
                    type: "performance",
                    title: "性能参数",
                    message: "设备信息默认处理完毕，用时：" + measure?.duration.toFixed(1) + "ms",
                    state: 0,
                    date: Date.now(),
                });
                performance.clearMarks("equipsInfoParseStart");
                performance.clearMarks("equipsInfoParseEnd");
                performance.clearMeasures("equipsInfoParseDone");
                performance.mark("equipsRegDataComputedStart");
                equipsRegData.forEach((v: Equip.EquipRegData) => this.equipRegDataComputed({ funid: v.sn, online: Boolean(v.isOnline), regAI: v.regai, regDI: v.regdi, regDO: v.regdo, diNum: v.dinum, doNum: v.donum }));
                performance.mark("equipsRegDataComputedEnd");
                performance.measure("equipsRegDataComputedDone", "equipsRegDataComputedStart", "equipsRegDataComputedEnd");
                const measure2 = performance.getEntriesByName("equipsRegDataComputedDone")[0];
                notification.addNotice({
                    id: notification.notices.length.toString(),
                    type: "performance",
                    title: "性能参数",
                    message: "首次设备数据解析完毕，用时：" + measure2?.duration.toFixed(1) + "ms",
                    state: 0,
                    date: Date.now(),
                });
                performance.clearMarks("equipsRegDataComputedStart");
                performance.clearMarks("equipsRegDataComputedEnd");
                performance.clearMeasures("equipsRegDataComputedDone");
                resolve(null);
            });
        },
        // 将设备原始信息处理为可用数据；为数据增加ai、ao、di、do通道信息数组，每个元素对应每个通道，元素包含通道所有信息；info与每个通道都增加alarm属性
        equipsInfoComputed() {
            return new Promise((resolve) => {
                this.equipsInfo.forEach(async (equipInfo) => {
                    const equipType = (this.equipsType as Equip.EquipType[]).find((v) => v.fEquipType == equipInfo?.fEquipType);
                    if (equipInfo && equipType) {
                        await defaultEquipInfoCheck(equipType, equipInfo);
                        equipInfo.fCreateData = new Date(equipInfo.fCreateData as unknown as string).getTime();
                        if ([2, 3, 20, 21, 22].includes(equipType.fLogicType) || equipType.fEquipType == "JYLoraKTC") {
                            equipInfo.isLora = true;
                            if (equipInfo.fUNID.length == 16) equipInfo.isHostLora = true;
                        }
                        equipInfo.fEquipImg = getEquipImageURL(equipInfo.fUNID, equipInfo.fEquipImg);
                        equipInfo.isDlcDam = equipType.fDLCRTC || equipType.fDLCAI || equipType.fDLCDI || equipType.fDLCScene || equipType.fDLCScene2 || equipType.fDLCMB || equipType.fDLC645 ? true : false;
                        equipInfo.dlc.dam.fDLCRTC = equipType.fDLCRTC;
                        equipInfo.dlc.dam.fDLCAI = equipType.fDLCAI;
                        equipInfo.dlc.dam.fDLCDI = equipType.fDLCDI;
                        equipInfo.dlc.dam.fDLCScene = equipType.fDLCScene;
                        equipInfo.dlc.dam.fDLCScene2 = equipType.fDLCScene2;
                        equipInfo.dlc.dam.fDLCMB = equipType.fDLCMB;
                        equipInfo.dlc.dam.fDLC645 = equipType.fDLC645;
                        // 处理AI通道信息
                        let fAINames = equipInfo.fAIName.split(";");
                        let fAIImgs = equipInfo.fAIImg.split(";");
                        let fAIAlarmImgs = equipInfo.fAIAlarmImg.split(";");
                        let fAIUNITs = equipInfo.fAIUNIT.split(";");
                        let fAIX1s = equipInfo.fAIX1.split(";");
                        let fAIX2s = equipInfo.fAIX2.split(";");
                        let fAIY1s = equipInfo.fAIY1.split(";");
                        let fAIY2s = equipInfo.fAIY2.split(";");
                        let fAlarmHs = equipInfo.fAlarmH.split(";");
                        let fAlarmLs = equipInfo.fAlarmL.split(";");
                        for (let i = 0; i < equipType.fAINum; i++) {
                            let index = equipInfo.fDODIMode.AIIndexArr[i];
                            equipInfo.dtAI[i] = {
                                index,
                                name: fAINames[index] || "",
                                img: getEquipImageURL(equipInfo.fUNID, fAIImgs[index] || "jyn_01.png"),
                                alarmImg: getEquipImageURL(equipInfo.fUNID, fAIAlarmImgs[index] || "com_alarm.gif"),
                                unit: fAIUNITs[index] || "",
                                x1: Number(fAIX1s[index] || 0),
                                x2: Number(fAIX2s[index] || 0),
                                y1: Number(fAIY1s[index] || 0),
                                y2: Number(fAIY2s[index] || 0),
                                alarmH: Number(fAlarmHs[index] || 0),
                                alarmL: Number(fAlarmLs[index] || 0),
                                value: equipInfo.dtAI[index] ? equipInfo.dtAI[index].value : null,
                                alarm: equipInfo.dtAI[index] ? equipInfo.dtAI[index].alarm : 0, // 是否报警，-1过低、0正常、1过高
                            };
                        }
                        // 处理AO通道信息
                        let fAONames = equipInfo.fAOName.split(";");
                        let fAOImgs = equipInfo.fAOImg.split(";");
                        let fAOUNITs = equipInfo.fAOUNIT.split(";");
                        let fAOX1s = equipInfo.fAOX1.split(";");
                        let fAOX2s = equipInfo.fAOX2.split(";");
                        let fAOY1s = equipInfo.fAOY1.split(";");
                        let fAOY2s = equipInfo.fAOY2.split(";");
                        let fAOMaxs = equipInfo.fAOMax.split(";");
                        let fAOMins = equipInfo.fAOMin.split(";");
                        for (let i = 0; i < equipType.fAONum; i++) {
                            let index = equipInfo.fDODIMode.AOIndexArr[i];
                            equipInfo.dtAO[i] = {
                                index,
                                name: fAONames[index] || "",
                                img: getEquipImageURL(equipInfo.fUNID, fAOImgs[index] || "jyn_01.png"),
                                unit: fAOUNITs[index] || "",
                                x1: Number(fAOX1s[index] || 0),
                                x2: Number(fAOX2s[index] || 0),
                                y1: Number(fAOY1s[index] || 0),
                                y2: Number(fAOY2s[index] || 0),
                                max: Number(fAOMaxs[index] || 0),
                                min: Number(fAOMins[index] || 0),
                                value: equipInfo.dtAO[index] ? equipInfo.dtAO[index].value : null,
                            };
                        }
                        // 处理DI通道信息
                        let fDINames = equipInfo.fDIName.split(";");
                        let fDIOnImgs = equipInfo.fDIOnImg.split(";");
                        let fDIOffImgs = equipInfo.fDIOffImg.split(";");
                        let fAlarmDIs = equipInfo.fAlarmDI.split(";");
                        let fAlarmDIHs = equipInfo.fAlarmDIH.split(";");
                        for (let i = 0; i < equipType.fDINum; i++) {
                            let index = equipInfo.fDODIMode.DIIndexArr[i];
                            equipInfo.dtDI[i] = {
                                index,
                                name: fDINames[index] || "",
                                onImg: getEquipImageURL(equipInfo.fUNID, fDIOnImgs[index] || "kg11.png"),
                                offImg: getEquipImageURL(equipInfo.fUNID, fDIOffImgs[index] || "kg11_0.png"),
                                alarmDI: fAlarmDIs[index] == "false" || fAlarmDIs[index] == "0" ? false : true,
                                alarmDIH: fAlarmDIHs[index] == "false" || fAlarmDIHs[index] == "0" ? false : true,
                                value: equipInfo.dtDI[index] ? equipInfo.dtDI[index].value : null,
                                alarm: equipInfo.dtDI[index] ? equipInfo.dtDI[index].alarm : 0,
                            };
                        }
                        // 处理DO通道信息
                        let [oprTypeStr, oprParamStr] = equipInfo.fDOUIMode.split("&");
                        let oprTypes = (oprTypeStr || "").split(";");
                        let oprParams = (oprParamStr || "").split(";");
                        let fDONames = equipInfo.fDOName.split(";");
                        let fDOOnImgs = equipInfo.fDOOnImg.split(";");
                        let fDOOffImgs = equipInfo.fDOOffImg.split(";");
                        for (let i = 0; i < equipType.fDONum; i++) {
                            let index = equipInfo.fDODIMode.DOIndexArr[i];
                            equipInfo.dtDO[i] = {
                                index,
                                name: fDONames[index] || "",
                                onImg: getEquipImageURL(equipInfo.fUNID, fDOOnImgs[index] || "kg03.png"),
                                offImg: getEquipImageURL(equipInfo.fUNID, fDOOffImgs[index] || "kg03_0.png"),
                                oprType: Number(oprTypes[index]) || 0,
                                oprParam: Number(oprParams[index]) || 0,
                                value: equipInfo.dtDO[index] ? equipInfo.dtDO[index].value : null,
                            };
                        }
                    }
                });
                resolve(null);
            });
        },
        // 将设备原始数据处理为可用数据（线性转换）（需要先调用处理原始信息函数；）；报警时alarm属性为true，否则false；其中一个通道的value===null时，代表没有获取到数据；AI的value属性为线性转换后的值；AI的alarm属性：-1下限报警、0正常、1上限报警；DI的alarm属性：0正常、1报警；
        equipRegDataComputed({ funid, online, regAI, regAO, regDI, regDO, diNum, doNum }: { funid: string; online?: boolean; regAI?: number[]; regAO?: number[]; regDI?: number[]; regDO?: number[]; diNum?: number; doNum?: number }) {
            const equipInfo = (this.equipsInfo as Equip.EquipInfo[]).find((v) => v.fUNID == funid);
            if (equipInfo) {
                if (online !== undefined) equipInfo.online = online;
                if (!equipInfo.online) {
                    const equipRegData = equipsRegData.find((v) => v.sn == equipInfo.fUNID);
                    if (equipRegData) {
                        const equipRegDataTime = new Date(equipRegData.aiTime!.slice(0, 10) + " " + equipRegData.aiTime!.slice(11, 19)).getTime();
                        if (Date.now() - equipRegDataTime < 600000) equipInfo.online = true;
                    }
                }
                // 处理数据
                if (regAI || regAO || regDI || regDO) {
                    const notificationStore = useNotification();
                    const history = {
                        sn: equipInfo.fUNID,
                        time: Date.now(),
                        aiValues: [] as number[],
                        diValues: [] as number[],
                        doValues: [] as number[],
                    };
                    if (regAI) {
                        // 处理AI数据
                        for (let i = 0; i < regAI.length; i++) {
                            let channel = equipInfo.dtAI.find((v) => v.index == i);
                            if (channel) {
                                channel.value = regAIAOParse({ value: Number(regAI[i]) || 0, fX1: channel.x1, fX2: channel.x2, fY1: channel.y1, fY2: channel.y2 });
                                let newChannelAlarm = channel.alarmL == 0 && channel.alarmH == 0 ? 0 : channel.value < channel.alarmL ? -1 : channel.value > channel.alarmH ? 1 : 0;
                                if (channel.alarm != newChannelAlarm) {
                                    channel.alarm = newChannelAlarm;
                                    notificationStore.addNotice(
                                        {
                                            id: (notificationStore.notices.length + 1).toString(),
                                            title: channel.alarm ? "设备报警" : "解除报警",
                                            message: `设备(${equipInfo.fName})${channel.alarm ? "发生AI" : "解除AI"}${channel.alarm ? (channel.alarm == -1 ? "下限" : "上限") : ""}报警，当前值：[${channel.value}]。`,
                                            type: channel.alarm ? "equipAlarm" : "info",
                                            date: Date.now(),
                                            state: 0,
                                            data: { fid: equipInfo.fID },
                                        },
                                        true
                                    );
                                }
                                history.aiValues.push(channel.value);
                            }
                        }
                    }
                    if (regAO) {
                        // 处理AO数据
                        for (let i = 0; i < regAO.length; i++) {
                            let channel = equipInfo.dtAO.find((v) => v.index == i);
                            if (channel) {
                                channel.value = regAIAOParse({ value: regAO[i] || 0, fX1: channel.x1, fX2: channel.x2, fY1: channel.y1, fY2: channel.y2 });
                            }
                        }
                    }
                    if (regDI && diNum) {
                        // 处理DI数据
                        let arr = regDIDOParse({ num: diNum, regData: regDI });
                        for (let i = 0; i < arr.length; i++) {
                            let channel = equipInfo.dtDI.find((v) => v.index == i);
                            if (channel) {
                                channel.value = Number(arr[i]);
                                let newChannelAlarm = channel.alarmDI == true && channel.alarmDIH == Boolean(channel.value) ? 1 : 0;
                                if (channel.alarm != newChannelAlarm) {
                                    channel.alarm = newChannelAlarm;
                                    notificationStore.addNotice(
                                        {
                                            id: (notificationStore.notices.length + 1).toString(),
                                            title: channel.alarm ? "设备报警" : "解除报警",
                                            message: `设备(${equipInfo.fName})${channel.alarm ? "发生DI" : "解除DI"}报警，当前值：[${channel.value ? "开" : "关"}]。`,
                                            type: channel.alarm ? "equipAlarm" : "info",
                                            date: Date.now(),
                                            state: 0,
                                            data: { fid: equipInfo.fID },
                                        },
                                        true
                                    );
                                }
                                history.diValues.push(channel.value);
                            }
                        }
                    }
                    if (regDO && doNum) {
                        // 处理DO数据
                        let arr = regDIDOParse({ num: doNum, regData: regDO });
                        for (let i = 0; i < arr.length; i++) {
                            let channel = equipInfo.dtDO.find((v) => v.index == i);
                            if (channel) {
                                channel.value = Number(arr[i] || 0);
                                history.doValues.push(channel.value);
                            }
                        }
                    }
                    equipInfo.alarm = equipInfo.dtAI.some((v) => v.alarm) || equipInfo.dtDI.some((v) => v.alarm);
                    regAI && regDI && regDO && equipInfo.histories.push(history);
                }
            }
        },
        // 将设备历史的原始数据处理为可用数据
        equipHistoryRegDataComputed({
            historiesRegData,
            aiX1s,
            aiY1s,
            aiX2s,
            aiY2s,
            diNum,
            doNum,
        }: {
            historiesRegData: { Time: string; regai: number[]; regdi: number[]; regdo: number[] }[];
            aiX1s: number[];
            aiY1s: number[];
            aiX2s: number[];
            aiY2s: number[];
            diNum: number;
            doNum: number;
        }) {
            return historiesRegData.map((historyRegData) => ({
                time: new Date(historyRegData.Time.slice(0, 19)).getTime(),
                aiValues: historyRegData.regai.map((v, i) => regAIAOParse({ value: Number(v) || 0, fX1: aiX1s[i], fX2: aiX2s[i], fY1: aiY1s[i], fY2: aiY2s[i] })),
                diValues: regDIDOParse({ num: diNum, regData: historyRegData.regdi }),
                doValues: regDIDOParse({ num: doNum, regData: historyRegData.regdo }),
            }));
        },
        // 设备信息配置
        equipInfoEdit({ msgtype = "EquipEdit", msginfo, useOld = false }: { msgtype?: "EquipEdit" | "CEquipParam"; msginfo: { fID: string; [propName: string]: any }; useOld?: boolean }): Promise<any> {
            return new Promise(async (resolve, reject) => {
                const equipInfo = this.equipsInfo.find((v) => v.fID == msginfo.fID);
                if (equipInfo) for (let key in msginfo) if (key != "fID") (equipInfo as any)[key] = deepClone(msginfo[key]);
                msginfo.fCamera && (msginfo.fCamera = JSON.stringify(msginfo.fCamera));
                msginfo.fParam && (msginfo.fParam = JSON.stringify(msginfo.fParam));
                msginfo.fAlarmType && (msginfo.fAlarmType = JSON.stringify(msginfo.fAlarmType));
                msginfo.fDODIMode && (msginfo.fDODIMode = JSON.stringify(msginfo.fDODIMode));
                let arr = objToEditArr(msginfo);
                if (useOld) {
                    let { data } = await equipV3EquipEdit({ msgtype, msginfo: JSON.stringify(arr), msgtoken: localStorage.getItem("access_token") || "" });
                    if (data != "OK") reject(data);
                } else {
                    let { data } = await equipeditEquipEdit({ msgtype, msginfo: JSON.stringify(arr) });
                    if (data.code != 200 || data.data != "OK") reject(data);
                }
                resolve(null);
            });
        },
        adjustAIComputed({ funid, adjustAI }: { funid: string; adjustAI: Equip.AdjustAI[] }) {
            const equipInfo = this.equipsInfo.find((v) => v.fUNID == funid);
            if (equipInfo) {
                equipInfo.adjust.ai = adjustAI;
            }
        },
        addEquipData({ funid, online, dtAIValues, dtAOValues, dtDIValues, dtDOValues }: { funid: string; online?: boolean; dtAIValues?: number[]; dtAOValues?: number[]; dtDIValues?: number[]; dtDOValues?: number[] }) {
            const equipInfo = (this.equipsInfo as Equip.EquipInfo[]).find((v) => v.fUNID == funid);
            if (equipInfo) {
                if (online !== undefined) equipInfo.online = online;
                if (!equipInfo.online) {
                    const equipRegData = equipsRegData.find((v) => v.sn == equipInfo.fUNID);
                    if (equipRegData) {
                        const equipRegDataTime = new Date(equipRegData.aiTime!.slice(0, 10) + " " + equipRegData.aiTime!.slice(11, 19)).getTime();
                        if (Date.now() - equipRegDataTime < 600000) equipInfo.online = true;
                    }
                }
                // 处理数据
                if (dtAIValues || dtAOValues || dtDIValues || dtDOValues) {
                    const notificationStore = useNotification();
                    const history = {
                        sn: equipInfo.fUNID,
                        time: Date.now(),
                        aiValues: [] as number[],
                        diValues: [] as number[],
                        doValues: [] as number[],
                    };
                    if (dtAIValues) {
                        // 处理AI数据
                        for (let i = 0; i < dtAIValues.length; i++) {
                            let channel = equipInfo.dtAI.find((v) => v.index == i);
                            if (channel) {
                                channel.value = dtAIValues[i];
                                let newChannelAlarm = channel.alarmL == 0 && channel.alarmH == 0 ? 0 : channel.value < channel.alarmL ? -1 : channel.value > channel.alarmH ? 1 : 0;
                                if (channel.alarm != newChannelAlarm) {
                                    channel.alarm = newChannelAlarm;
                                    notificationStore.addNotice(
                                        {
                                            id: (notificationStore.notices.length + 1).toString(),
                                            title: channel.alarm ? "设备报警" : "解除报警",
                                            message: `设备(${equipInfo.fName})${channel.alarm ? "发生AI" : "解除AI"}${channel.alarm ? (channel.alarm == -1 ? "下限" : "上限") : ""}报警，当前值：[${channel.value}]。`,
                                            type: channel.alarm ? "equipAlarm" : "info",
                                            date: Date.now(),
                                            state: 0,
                                            data: { fid: equipInfo.fID },
                                        },
                                        true
                                    );
                                }
                                history.aiValues.push(channel.value);
                            }
                        }
                    }
                    if (dtAOValues) {
                        // 处理AO数据
                        for (let i = 0; i < dtAOValues.length; i++) {
                            let channel = equipInfo.dtAO.find((v) => v.index == i);
                            if (channel) {
                                channel.value = dtAOValues[i];
                            }
                        }
                    }
                    if (dtDIValues) {
                        // 处理DI数据
                        for (let i = 0; i < dtDIValues.length; i++) {
                            let channel = equipInfo.dtDI.find((v) => v.index == i);
                            if (channel) {
                                channel.value = dtDIValues[i];
                                let newChannelAlarm = channel.alarmDI == true && channel.alarmDIH == Boolean(channel.value) ? 1 : 0;
                                if (channel.alarm != newChannelAlarm) {
                                    channel.alarm = newChannelAlarm;
                                    notificationStore.addNotice(
                                        {
                                            id: (notificationStore.notices.length + 1).toString(),
                                            title: channel.alarm ? "设备报警" : "解除报警",
                                            message: `设备(${equipInfo.fName})${channel.alarm ? "发生DI" : "解除DI"}报警，当前值：[${channel.value ? "开" : "关"}]。`,
                                            type: channel.alarm ? "equipAlarm" : "info",
                                            date: Date.now(),
                                            state: 0,
                                            data: { fid: equipInfo.fID },
                                        },
                                        true
                                    );
                                }
                                history.diValues.push(channel.value);
                            }
                        }
                    }
                    if (dtDOValues) {
                        // 处理DO数据
                        for (let i = 0; i < dtDOValues.length; i++) {
                            let channel = equipInfo.dtDO.find((v) => v.index == i);
                            if (channel) {
                                channel.value = dtDOValues[i] || 0;
                                history.doValues.push(channel.value);
                            }
                        }
                    }
                    equipInfo.alarm = equipInfo.dtAI.some((v) => v.alarm) || equipInfo.dtDI.some((v) => v.alarm);
                    dtAIValues && dtDIValues && dtDOValues && equipInfo.histories.push(history);
                }
            }
        },
    },
});
